/*  PCSX2 - PS2 Emulator for PCs
 *  Copyright (C) 2002-2010  PCSX2 Dev Team
 *
 *  PCSX2 is free software: you can redistribute it and/or modify it under the terms
 *  of the GNU Lesser General Public License as published by the Free Software Found-
 *  ation, either version 3 of the License, or (at your option) any later version.
 *
 *  PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 *  PURPOSE.  See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with PCSX2.
 *  If not, see <http://www.gnu.org/licenses/>.
 */

#include "PrecompiledHeader.h"
#include "App.h"
#include "ConfigurationPanels.h"
#include "Common.h"
#include "AppConfig.h"

#include "Utilities/ScopedPtr.h"
#include "wx/file.h"

#include <wx/dir.h>
#include <wx/filepicker.h>
#include <wx/listbox.h>
#include <wx/listctrl.h>

using namespace pxSizerFlags;

// =====================================================================================================
//  GameSelectorPanel
// =====================================================================================================

Panels::GameSelectorPanel::GameSelectorPanel( wxWindow* parent )
	: BaseSelectorPanel( parent )
{
	SetMinWidth( 480 );

	m_ComboBox		= new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE | wxLB_SORT | wxLB_NEEDED_SB );
	m_FolderPicker	= new DirPickerPanel( this, FolderId_Games,
		_("Game dir:"),
		_("Select folder with PS2 games")
	);
	m_ENABLEskipBIOS = new pxCheckBox( this, _("Enable Skip BIOS"));
	m_ENABLEskipBIOS->SetToolTip( pxE( ".Tooltip:GameSelecto:enableSkipBIOS", wxEmptyString));

	m_ComboBox->SetFont( wxFont( m_ComboBox->GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) );
	m_ComboBox->SetMinSize( wxSize( wxDefaultCoord, std::max( m_ComboBox->GetMinSize().GetHeight(), 200 ) ) );
	
	m_FolderPicker->SetStaticDesc( _("Click the Browse button to select a different folder where PCSX2 will look for games.") );

	wxButton* refreshButton  = new wxButton( this, wxID_ANY,   _("Refresh list") );
	wxButton* BootCDVDButton = new wxButton( this, wxID_ANY,   _("Boot Plugin")  );

	*this	+= Label(_("Select a game:"));
	*this	+= m_ComboBox		| StdExpand();
	*this	+= refreshButton    | pxBorder(wxLEFT, StdPadding);
	*this   += BootCDVDButton   | pxBorder(wxLEFT, StdPadding);
	*this   += m_ENABLEskipBIOS | StdExpand();
	*this	+= 8;
	*this	+= m_FolderPicker	| StdExpand();
	g_Conf->BaseFilenames.Games

	Connect( refreshButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GameSelectorPanel::OnRefreshSelections) );
	Connect( BootCDVDButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(GameSelectorPanel::BootGameCDVD)       );
	Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED,	wxCommandEventHandler(GameSelectorPanel::BootGameIso)                        );
}

Panels::GameSelectorPanel::~GameSelectorPanel() throw ()
{
}

void Panels::GameSelectorPanel::Apply()
{
	if( !m_GamesList ) return;

	int sel = m_ComboBox->GetSelection();

	Pcsx2Config::GameSelectorOptions& opts( g_Conf->EmuOptions.GameSelector );
	opts.enableSkipBIOS			= m_ENABLEskipBIOS->GetValue();
	g_Conf->BaseFilenames.Games = (*m_GamesList)[(int)m_ComboBox->GetClientData(sel)];
}
void Panels::GameSelectorPanel::AppStatusEvent_OnSettingsApplied()
{
	AppStatusEvent_OnSettingsApplied2( g_Conf->EmuOptions.GameSelector );
}
void Panels::GameSelectorPanel::AppStatusEvent_OnSettingsApplied2( const Pcsx2Config::GameSelectorOptions& opts )
{
	m_ENABLEskipBIOS	->SetValue(opts.enableSkipBIOS);
}

bool Panels::GameSelectorPanel::ValidateEnumerationStatus()
{
	bool validated = true;

	ScopedPtr<wxArrayString> gameslist( new wxArrayString() );

	if( m_FolderPicker->GetPath().Exists() )
	{
		wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), gameslist, L"*.iso",  wxDIR_FILES );
		wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), gameslist, L"*.mdf",  wxDIR_FILES );
		wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), gameslist, L"*.nrg",  wxDIR_FILES );
		wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), gameslist, L"*.bin",  wxDIR_FILES );
		wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), gameslist, L"*.img",  wxDIR_FILES );
		wxDir::GetAllFiles( m_FolderPicker->GetPath().ToString(), gameslist, L"*.dump", wxDIR_FILES );
	}

	if( !m_GamesList || (*gameslist != *m_GamesList) )
		validated = false;

	m_GamesList.SwapPtr( gameslist );
	return validated;
}

void Panels::GameSelectorPanel::DoRefresh()
{
	if( !m_GamesList ) return;

	m_ComboBox->Clear();

	const wxFileName right( g_Conf->FullpathToGames() );

	for( size_t i=0; i<m_GamesList->GetCount(); ++i )
	{
		wxString description;
		if( !IsGAME((*m_GamesList)[i], description) ) continue;
		int sel = m_ComboBox->Append( description, (void*)i );

		if( wxFileName((*m_GamesList)[i] ) == right )
			m_ComboBox->SetSelection( sel );
	}
}

void Panels::GameSelectorPanel::BootGameCDVD( wxCommandEvent& evt )
{
	Pcsx2Config::GameSelectorOptions& opts( g_Conf->EmuOptions.GameSelector );
	opts.enableSkipBIOS			= m_ENABLEskipBIOS->GetValue();
	if(EmuConfig.GameSelector.enableSkipBIOS)
		g_Conf->EmuOptions.UseBOOT2Injection = true;
	else
		g_Conf->EmuOptions.UseBOOT2Injection = false;
	ScopedCoreThreadPopup core;
	g_Conf->CdvdSource = CDVDsrc_Plugin;
	core.DisallowResume();
	sApp.SysExecute( g_Conf->CdvdSource );
}

void Panels::GameSelectorPanel::BootGameIso( wxCommandEvent& evt )
{
	Pcsx2Config::GameSelectorOptions& opts( g_Conf->EmuOptions.GameSelector );
	opts.enableSkipBIOS			= m_ENABLEskipBIOS->GetValue();
	int sel = m_ComboBox->GetSelection();
	g_Conf->BaseFilenames.Games = (*m_GamesList)[(int)m_ComboBox->GetClientData(sel)];

	if(EmuConfig.GameSelector.enableSkipBIOS)
		g_Conf->EmuOptions.UseBOOT2Injection = true;
	else
		g_Conf->EmuOptions.UseBOOT2Injection = false;

	ScopedCoreThreadPopup core;
	g_Conf->CdvdSource = CDVDsrc_Iso;
	CDVDsys_SetFile( CDVDsrc_Iso, (*m_GamesList)[(int)m_ComboBox->GetClientData(sel)] );
	g_Conf->CurrentIso = (*m_GamesList)[(int)m_ComboBox->GetClientData(sel)];
	
	bool selector = g_Conf->CurrentIso.IsEmpty();
	if( !selector && !wxFileExists(g_Conf->CurrentIso) )
	{
			wxDialogWithHelpers dialog( this, _("ISO file not found!") );
			dialog += dialog.Heading(
				_("An error occurred while trying to open the file:\n\n") + g_Conf->CurrentIso + L"\n\n" +
				_("Error: The configured ISO file does not exist.  Click OK to select a new ISO source for CDVD.")
			);

			selector = true;
	}

		if( selector )
		{
			wxString result;

			SysUpdateIsoSrcFile( result );
		}

	if( SysHasValidState() )
	{
		wxDialogWithHelpers dialog( this, _("Confirm PS2 Reset") );
	}

	core.DisallowResume();
	sApp.SysExecute( g_Conf->CdvdSource );
}
